﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Web;
using CSP.Model.Entities;
using CSP.Model.Model;
using Microsoft.Office.Server.ActivityFeed;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using Twitterizer.Framework;

namespace CSP.Model.Presenter
{
    public class WhatsOnYourMindPresenter
    {
        private IWhatsOnYourMindPresenter view = null;
        private ModelManager model = new ModelManager();

        public WhatsOnYourMindPresenter(IWhatsOnYourMindPresenter iView)
        {
            view = iView;
        }

        public void Load()
        {
            try
            {
                view.Title = "";
                view.UserImage = model.GetCurrentUserImage();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //public void PostPeep()
        //{



        //    try
        //    {
        //        ModelManager m = new ModelManager();
        //        string userImage = m.GetCurrentUserImage();
        //        Peep peep = new Peep(view.Title, view.User, view.Date, DateTime.Now.TimeOfDay.ToString(), userImage, view.PostToFB, view.PostToTwitter);
        //        SPWebApplication webApp = SPContext.Current.Site.WebApplication;
        //        SPSiteCollection siteColl = webApp.Sites;


        //        //siteColl = SPContext.Current.Current.Site;

        //        string webAppUrl = siteColl[0].Url;

        //        //site = SPContext.Current.Web;
        //        //string rootweb = site.ParentWeb.Url;
        //        //view.SiteURL = rootweb;
        //        //Write to the site collection

        //        //write to the root location
        //        //result = model.PostPeep(peep, view.ListName, rootweb);
        //        string t = peep.Title;

        //        if (view.PostToTwitter)
        //        {
        //            if (t.Length > 140)
        //                t = t.Substring(0, 140);

        //            if (view.PostToFB)
        //            {
        //                if (t.Length > 136)
        //                    t = t.Substring(0, 136);
        //                t += " #fb";
        //            }

        //            try
        //            {
        //                //Twitter tweet = new Twitter(view.User, view.Password, "Gov 2.0 My Peeps");
        //                Twitter tweet = new Twitter(view.User, view.Password);
        //                tweet.Status.Update(t);
        //            }
        //            catch
        //            {
        //                //Do nothing, the post is successfull but for some reason the DLL rthroughs an uinecessary error.
        //            }
        //        }

        //        bool result = model.PostPeep(peep, view.ListName, webAppUrl);
        //    }
        //    catch (Exception ex)
        //    {

        //    }
        //}

        public void PostPeep()
        {
            using (SPMonitoredScope scoped = new SPMonitoredScope("PostPeep()"))
            {
                ModelManager m = new ModelManager();
                string userImage = m.GetCurrentUserImage();
                Peep peep = new Peep(view.Title, view.User, view.Date, DateTime.Now.TimeOfDay.ToString(), userImage, view.PostToFB, view.PostToTwitter);

                /// Profile status update
                bool flag_updateInternalStatus = false;
                if (view.PostToTwitter == false && view.PostToFB == false)
                    flag_updateInternalStatus = true;

                UserProfile meProfile = PostMyProfileStatusUpdate(peep.Title, flag_updateInternalStatus);

                List<ActivityEvent> activityEvents = new List<ActivityEvent>();

                if (view.PostToTwitter)
                {
                    PostTweeterUpdate(peep.Title);
                    // Generate new feed
                    activityEvents.Add(this.GenerateActivityEvent_TweetUpdate(meProfile, peep.Title));
                }

                if (view.PostToFB)
                {
                    PostFacebookUpdate(peep.Title);
                    // Generate new feed
                    activityEvents.Add(this.GenerateActivityEvent_FacebookUpdate(meProfile, peep.Title));
                }

                // Multicast custom feeds
                if(activityEvents.Count > 0) MulticastPublishedEvents(SPContext.Current.Site, activityEvents);
            }
        }

        protected UserProfile PostMyProfileStatusUpdate(string Message, bool Post)
        {
            try
            {
                UserProfileManager usrProfileManager = new UserProfileManager(SPServiceContext.Current);
                UserProfile meProfile = usrProfileManager.GetUserProfile(SPContext.Current.Web.CurrentUser.LoginName);
                if (meProfile != null && Post)
                {
                    meProfile["SPS-StatusNotes"].Value = Message;
                    try
                    {
                        meProfile.Commit();
                    }
                    catch { };
                }
                return meProfile;
            }
            catch
            { }

            return null;
        }

        protected void PostTweeterUpdate(string Message)
        {
            // Trim to 140 chars
            if (Message.Length > 140)
                Message = Message.Substring(0, 140);

            try
            {
                Twitter tweet = new Twitter(view.User, view.Password);
                tweet.Status.Update(Message);
            }
            catch
            {
                //Do nothing, the post is successfull but for some reason the DLL rthroughs an uinecessary error.
            }
        }
        protected void PostFacebookUpdate(string Message)
        {
            try
            {
                Facebook.Session.ConnectSession connectsession = new Facebook.Session.ConnectSession(view.FBAPIkey, view.FBSecretkey);
                Facebook.Rest.Api api = new Facebook.Rest.Api(connectsession);

                //assume you have offline_access extended permission, and that you saved the non-expiring session key
                //and userid for future use
                api.Session.SessionKey = view.FBSessionKey;
                api.Session.UserId = view.FBUserID;

                #region customizations of the post
                Facebook.Rest.attachment_media_image myimage = new Facebook.Rest.attachment_media_image();
                //href is the link for the image if you click on it
                myimage.href = "http://mydomain.com";
                myimage.src = "http://mydomain.com/image.png";
                List<Facebook.Rest.attachment_media> mymedia = new List<Facebook.Rest.attachment_media>();
                mymedia.Add(myimage);

                Facebook.Rest.attachment myattachment = new Facebook.Rest.attachment();

                //name is bold heading for entry, to right of image
                myattachment.name = "Title of your post";
                //href is the link target for the 'name'
                myattachment.href = "http://mydomain.com";

                //caption is the long article text below the name
                myattachment.caption = "Here is the main message for the wall/stream post";

                //description appears under image
                myattachment.description = "Something to describe the image";

                myattachment.media = mymedia;

                IList<Facebook.Schema.action_link> myactionlinks = new List<Facebook.Schema.action_link>();
                Facebook.Schema.action_link myactionlink = new Facebook.Schema.action_link();
                myactionlink.href = "http://mydomain.com";
                myactionlink.text = "Description for hyperlink";
                myactionlinks.Add(myactionlink);
                #endregion

                api.Stream.Publish(Message, null, null, "", view.FBUserID);
            }
            catch { }
        }

        protected ActivityEvent GenerateActivityEvent_TweetUpdate(UserProfile userProfile, string Message)
        {
            string ActivityApplicationTitle_eGovCustomFeeds = "ActivityApplicationTitle_eGovCustomFeeds";
            string feedActivityName = "ActivityName_TweetUpdate";
            string ActivityTemplateTitle_TweetUpdate = "ActivityTemplate_TweetUpdate";

            return GenerateActivityEvent(ActivityApplicationTitle_eGovCustomFeeds, feedActivityName, ActivityTemplateTitle_TweetUpdate, userProfile, Message);
        }
        protected ActivityEvent GenerateActivityEvent_FacebookUpdate(UserProfile userProfile, string Message)
        {
            string ActivityApplicationTitle_eGovCustomFeeds = "ActivityApplicationTitle_eGovCustomFeeds";
            string feedActivityName = "ActivityName_FacebookUpdate";
            string ActivityTemplateTitle_FacebookUpdate = "ActivityTemplate_FacebookUpdate";

            return GenerateActivityEvent(ActivityApplicationTitle_eGovCustomFeeds, feedActivityName, ActivityTemplateTitle_FacebookUpdate, userProfile, Message);
        }

        protected void MulticastPublishedEvents(SPSite site, List<ActivityEvent> activityEvents)
        {
            Guid SPSiteGuid = site.ID;
            if (activityEvents.Count == 0) return;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite Site = new SPSite(SPSiteGuid))
                {
                    HttpContext currentContext = HttpContext.Current;
                    try
                    {
                        HttpContext.Current = null;
                        SPServiceContext spContext = SPServiceContext.GetContext(Site);

                        UserProfileManager userManager = new UserProfileManager(spContext);
                        string accPoolProfileName = WindowsIdentity.GetCurrent().Name;
                        UserProfile accPoolProfile = null;
                        if (userManager.UserExists(accPoolProfileName)) accPoolProfile = userManager.GetUserProfile(accPoolProfileName);
                        else userManager.CreateUserProfile(accPoolProfileName);

                        ActivityManager activityManager = new ActivityManager(accPoolProfile, spContext);

                        /// Method code
                        List<long> publishers = new List<long>();
                        foreach (ActivityEvent activityEvent in activityEvents)
                        {
                            if (!publishers.Contains(activityEvent.Owner.Id))
                                publishers.Add(activityEvent.Owner.Id);
                        }

                        Dictionary<long, MinimalPerson> owners;
                        Dictionary<long, List<MinimalPerson>> colleaguesOfOwners;
                        ActivityFeedGatherer.GetUsersColleaguesAndRights(activityManager, publishers, out owners, out colleaguesOfOwners);

                        Dictionary<long, List<ActivityEvent>> eventsPerOwner;
                        ActivityFeedGatherer.MulticastActivityEvents(activityManager, activityEvents, colleaguesOfOwners, out eventsPerOwner);

                        List<ActivityEvent> eventsToMulticast;
                        ActivityFeedGatherer.CollectActivityEventsToConsolidate(eventsPerOwner, out eventsToMulticast);
                        WriteEvents(activityManager, eventsToMulticast);
                        // End of method code
                    }
                    catch (UnauthorizedAccessException securityEx)
                    { }
                    catch (SPException sharepointEx)
                    { }
                    finally
                    {
                        HttpContext.Current = currentContext;
                    }
                }
            });

        }
        protected void WriteEvents(ActivityManager ActManager, List<ActivityEvent> events)
        {
            int startIndex = 0;
            while (startIndex + ActManager.MaxEventsPerBatch < events.Count)
            {
                ActivityFeedGatherer.BatchWriteActivityEvents(events, startIndex, ActManager.MaxEventsPerBatch);
                startIndex += ActManager.MaxEventsPerBatch;
            }

            ActivityFeedGatherer.BatchWriteActivityEvents(events, startIndex, events.Count - startIndex);
        }
        protected ActivityEvent GenerateActivityEvent(string feedApplicationName, string feedActivityName, string ActivityTemplateName, UserProfile userProfile, string Message)
        {
            ActivityEvent activityEvent = null;
            Guid SPSiteGuid = SPContext.Current.Site.ID;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite Site = new SPSite(SPSiteGuid))
                {
                    HttpContext currentContext = HttpContext.Current;
                    try
                    {
                        HttpContext.Current = null;
                        SPServiceContext spContext = SPServiceContext.GetContext(Site);

                        UserProfileManager userManager = new UserProfileManager(spContext);
                        string accPoolProfileName = WindowsIdentity.GetCurrent().Name;
                        UserProfile accPoolProfile = null;
                        if (userManager.UserExists(accPoolProfileName)) accPoolProfile = userManager.GetUserProfile(accPoolProfileName);
                        else userManager.CreateUserProfile(accPoolProfileName);
                        ActivityManager activityManager = new ActivityManager(accPoolProfile, spContext);

                        ActivityApplication actApplication_TweetUpdate = activityManager.ActivityApplications[feedApplicationName];
                        ActivityType actType_TweetUpdate = actApplication_TweetUpdate.ActivityTypes[feedActivityName];

                        Entity owner = new MinimalPerson(userProfile).CreateEntity(activityManager);
                        Entity publisher = new MinimalPerson(userProfile).CreateEntity(activityManager);

                        activityEvent = ActivityEvent.CreateActivityEvent(activityManager, actType_TweetUpdate.ActivityTypeId, owner, publisher);
                        activityEvent.Name = ActivityTemplateName;
                        activityEvent.ItemPrivacy = (int)Privacy.Public;
                        activityEvent.Owner = owner;
                        activityEvent.Publisher = publisher;
                        activityEvent.Value = Message;
                        activityEvent.Commit();
                    }
                    catch (UnauthorizedAccessException SecurityException)
                    { }
                    finally
                    {
                        HttpContext.Current = currentContext;
                    }
                }
            });

            return activityEvent;
        }


        public void DeleteAllPeeps()
        {
            model.DeleteAllPeeps(view.ListName, view.SiteURL);
        }

    }
}
